"""
交易执行器
支持现货和永续合约
"""
import time
from typing import Optional, Dict, List, Tuple
from datetime import datetime
from src.okx.client import OKXClient
from src.trading.position import PositionManager, Trade
from src.trading.risk import RiskManager, RiskControl
from src.costs.calculator import CostCalculator
from src.utils.logger import get_logger

logger = get_logger(__name__)


class TradeExecutor:
    """交易执行器"""

    def __init__(self, client: OKXClient, trade_type: str = "spot",
                 leverage: float = 1.0, cost_calculator: Optional[CostCalculator] = None):
        """
        初始化

        Args:
            client: OKX API客户端
            trade_type: 交易类型 (spot/perpetual)
            leverage: 杠杆倍数
            cost_calculator: 成本计算器
        """
        self.client = client
        self.trade_type = trade_type
        self.leverage = leverage
        self.position_manager = PositionManager()
        self.cost_calculator = cost_calculator or CostCalculator()

        # 如果是永续合约，设置杠杆
        if trade_type == "perpetual" and leverage > 1:
            self.client.set_leverage(leverage)

        logger.info(f"交易执行器初始化: 类型={trade_type}, 杠杆={leverage}x")

    def execute_buy(self, symbol: str, quantity: float, price: Optional[float] = None,
                   order_type: str = "market") -> Tuple[bool, Optional[Trade]]:
        """
        执行买入

        Args:
            symbol: 交易对
            quantity: 买入数量
            price: 限价单价格
            order_type: 订单类型 (market/limit)

        Returns:
            (是否成功, Trade对象或None)
        """
        logger.info(f"执行买入: {symbol}, 数量={quantity}, 价格={price}, 类型={order_type}")

        # 如果是永续合约且不存在开仓，设置多头方向
        if self.trade_type == "perpetual":
            # 对于永续合约，buy对应做多
            actual_side = "buy"
        else:
            actual_side = "buy"

        # 下单
        result = self.client.place_order(
            symbol=symbol,
            side=actual_side,
            order_type=order_type,
            quantity=quantity,
            price=price
        )

        if not result.success:
            logger.error(f"买入订单失败: {result.message}")
            return False, None

        # 获取成交价格 (简化: 假设成交价格为指定价格或市场价)
        if price is None:
            ticker = self.client.get_ticker(symbol)
            price = ticker['last_price'] if ticker else 0
        else:
            price = price

        # 创建持仓记录
        trade = self.position_manager.open_position(
            symbol=symbol,
            side="long",
            price=price,
            quantity=quantity,
            timestamp=datetime.now()
        )

        trade.order_ids.append(result.order_id)

        logger.info(f"买入成功: 交易ID={trade.trade_id}, 成交价={price}, 数量={quantity}")

        return True, trade

    def execute_sell(self, symbol: str, quantity: float, price: Optional[float] = None,
                    order_type: str = "market") -> Tuple[bool, Optional[Trade]]:
        """
        执行卖出

        Args:
            symbol: 交易对
            quantity: 卖出数量
            price: 限价单价格
            order_type: 订单类型 (market/limit)

        Returns:
            (是否成功, Trade对象或None)
        """
        logger.info(f"执行卖出: {symbol}, 数量={quantity}, 价格={price}, 类型={order_type}")

        # 获取现仓位
        position = self.position_manager.get_active_position(symbol)
        if not position:
            logger.warning(f"没有活跃持仓: {symbol}")
            return False, None

        # 下单
        result = self.client.place_order(
            symbol=symbol,
            side="sell",
            order_type=order_type,
            quantity=quantity,
            price=price
        )

        if not result.success:
            logger.error(f"卖出订单失败: {result.message}")
            return False, None

        # 获取成交价格
        if price is None:
            ticker = self.client.get_ticker(symbol)
            price = ticker['last_price'] if ticker else 0
        else:
            price = price

        # 计算成本
        cost_info = self.cost_calculator.calculate_profit_loss(
            entry_price=position.entry_price,
            exit_price=price,
            quantity=quantity,
            trade_type=self.trade_type
        )

        # 平仓
        closed_trade = self.position_manager.close_position(
            trade_id=position.trade_id,
            exit_price=price,
            exit_qty=quantity,
            timestamp=datetime.now(),
            reason="manual",
            cost_info=cost_info
        )

        closed_trade.order_ids.append(result.order_id)

        logger.info(f"卖出成功: 交易ID={closed_trade.trade_id}, 成交价={price}, "
                   f"盈亏={closed_trade.pnl:.2f} ({closed_trade.pnl_pct:.2f}%)")

        return True, closed_trade

    def execute_short(self, symbol: str, quantity: float, price: Optional[float] = None,
                     order_type: str = "market") -> Tuple[bool, Optional[Trade]]:
        """
        执行做空 (仅永续合约)

        Args:
            symbol: 交易对
            quantity: 做空数量
            price: 限价单价格
            order_type: 订单类型 (market/limit)

        Returns:
            (是否成功, Trade对象或None)
        """
        if self.trade_type != "perpetual":
            logger.error("做空仅支持永续合约交易")
            return False, None

        logger.info(f"执行做空: {symbol}, 数量={quantity}, 价格={price}, 类型={order_type}")

        # 下单
        result = self.client.place_order(
            symbol=symbol,
            side="sell",
            order_type=order_type,
            quantity=quantity,
            price=price
        )

        if not result.success:
            logger.error(f"做空订单失败: {result.message}")
            return False, None

        # 获取成交价格
        if price is None:
            ticker = self.client.get_ticker(symbol)
            price = ticker['last_price'] if ticker else 0
        else:
            price = price

        # 创建持仓记录
        trade = self.position_manager.open_position(
            symbol=symbol,
            side="short",
            price=price,
            quantity=quantity,
            timestamp=datetime.now()
        )

        trade.order_ids.append(result.order_id)

        logger.info(f"做空成功: 交易ID={trade.trade_id}, 成交价={price}, 数量={quantity}")

        return True, trade

    def close_position(self, symbol: str, reason: str = "manual") -> bool:
        """
        平仓特定交易对的所有持仓

        Args:
            symbol: 交易对
            reason: 平仓原因

        Returns:
            是否成功
        """
        position = self.position_manager.get_active_position(symbol)
        if not position:
            logger.warning(f"没有活跃持仓: {symbol}")
            return False

        # 获取当前价格
        ticker = self.client.get_ticker(symbol)
        if not ticker:
            logger.error(f"无法获取最新价格: {symbol}")
            return False

        price = ticker['last_price']

        # 执行平仓
        if position.side == "long":
            success, _ = self.execute_sell(symbol, position.entry_qty, price=price)
        else:  # short
            # 做空平仓: 买入
            success, _ = self.execute_buy(symbol, position.entry_qty, price=price)

        if success:
            # 更新平仓原因
            closed = self.position_manager.closed_trades[-1]
            closed.reason = reason

        return success

    def get_active_positions(self) -> List[Trade]:
        """获取所有活跃持仓"""
        return self.position_manager.get_active_positions()

    def get_trade_history(self, symbol: str = None) -> List[Trade]:
        """获取交易历史"""
        return self.position_manager.get_closed_trades(symbol)

    def get_stats(self) -> Dict:
        """获取交易统计"""
        return self.position_manager.calculate_stats()
